<?php
class memcached{
	private $Host;
	private $Port;
	private $Handle;
	public function init($params=array()){
		foreach($params as $key => $var){
			$this->$key=is_array($this->$key)?array_merge($this->$key,$var):$var;
		}
	}
	public static function Connect($Host,$Port,$Timeout=5){
		$this->Host = $Host;
		$this->Port = $Port;
		if($this->Handle=@fsockopen($Ret->Host,$Ret->Port,NULL,NULL,$Timeout)){
			return true;
		}else{
			return false;
		}
	}
	public function Set($Key,$Value,$TTL=0){
		return $this->SetOp($Key, $Value,$TTL,'set');
	}
	public function Add($Key,$Value,$TTL=0){
		return $this->SetOp($Key,$Value,$TTL,'add');
	}
	public function Append($Key, $Value,$TTL=0){
		return $this->SetOp($Key, $Value,$TTL,'append');
	}
	public function Prepend($Key,$Value,$TTL=0){
		return $this->SetOp($Key,$Value,$TTL,'prepend');
	}
	public function Replace($Key,$Value,$TTL=0){
		return $this->SetOp($Key,$Value,$TTL,'replace');
	}
	public function Get($Key){
		$this->WriteLine('get '.$Key);
		$Ret='';
		$Header=$this->ReadLine();
		// Header not found => value not found
		if($Header == 'END')
			return false;
		while(($Line=$this->ReadLine())!= 'END')
			$Ret.=$Line;
		if($Ret == '')
			return false;
		$Header = explode(' ', $Header);
		if($Header[0] != 'VALUE' || $Header[1] != $Key)
			throw new Exception('unexcpected response format');
		$Meta = $Header[2];
		$Len = $Header[3];
		return $Ret;
	}
	public function Delete($Key){
		return $this->WriteLine('delete '.$Key,true)!='NOT_FOUND';
	}
	public function Incr($Key, $Amount = 1){
		return ($Ret=$this->WriteLine('incr '.$Key .' ' .$Amount,true))!= 'NOT_FOUND'?$Ret:false;
	}
	public function Decr($Key, $Amount = 1){
		return ($Ret=$this->WriteLine('decr '.$Key.' '.$Amount,true)) != 'NOT_FOUND'?$Ret:false;
	}
	public function Stats($Key = NULL){
		$Ret = array();
		$this->WriteLine('stats');
		while(($Line=$this->ReadLine())!= 'END'){
			$Line = explode(' ', $Line);
			if($Line[0] != 'STAT')
				throw new Exception('unexcpected response format');
			$Ret[$Line[1]] = $Line[2];
		}
		if($Key)
			return isset($Ret[$Key]) ? $Ret[$Key] : false;
		return $Ret;
	}
	public function Quit(){
		$this->WriteLine('quit');
	}
	private function SetOp($Key, $Value, $TTL, $Op){
		$this->WriteLine($Op . ' ' . $Key . ' 0 ' . $TTL . ' ' . strlen($Value));
		$this->WriteLine($Value);
		return $this->ReadLine() == 'STORED';
	}
	private function WriteLine($Command, $Response = false){
		fwrite($this->Handle, $Command . "\r\n");
		if($Response)
			return $this->ReadLine();
		return true;
	}
	private function ReadLine(){
		return rtrim(fgets($this->Handle), "\r\n");
	}
	private function __construct(){
	}
}
?>